package com.denghq.projectbuilder.component.logging.listener;

import com.denghq.projectbuilder.component.logging.autoconfigure.LogConfigProperties;
import com.denghq.projectbuilder.component.logging.autoconfigure.LogLevelConfigProperties;
import com.denghq.projectbuilder.component.logging.bean.LogLevelConfigDetail;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.cloud.endpoint.event.RefreshEvent;
import org.springframework.context.event.EventListener;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class LoggingConfigChangeListener {

    private static Log log = LogFactory.getLog(LoggingConfigChangeListener.class);
    private ContextRefresher refresh;
    private AtomicBoolean ready = new AtomicBoolean(false);
    private LogLevelConfigProperties logLevelConfigProperties;

    private LogConfigProperties logConfigProperties;
    private String appNo;
    private LoggingSystem loggingSystem;

    public LoggingConfigChangeListener(String appNo, LoggingSystem loggingSystem, LogConfigProperties logConfigProperties, LogLevelConfigProperties logLevelConfigProperties, ContextRefresher refresh) {
        this.appNo = appNo;
        this.logLevelConfigProperties = logLevelConfigProperties;
        this.logConfigProperties = logConfigProperties;
        this.refresh = refresh;
        this.loggingSystem = loggingSystem;
    }

    @EventListener
    public void handle(ApplicationReadyEvent event) {
        setLogLevel();
        this.ready.compareAndSet(false, true);
    }

    private void setLogLevel() {

        List<LogLevelConfigDetail> logLevelDetails = logLevelConfigProperties.getLogLevelDetails();
        if (!CollectionUtils.isEmpty(logLevelDetails)) {
            logLevelDetails.forEach(e -> {
                if (appNo.equals(e.getAppNo())) {
                    Boolean enableSqlLog = e.getEnableSqlLog();
                    String rootLogLevel = e.getRootLogLevel();
                    loggingSystem.setLogLevel(logConfigProperties.getRootLogName(), LogLevel.valueOf(rootLogLevel));
                    logConfigProperties.getSqlPackages().forEach(sqlLogName -> {
                        if (enableSqlLog) {
                            loggingSystem.setLogLevel(sqlLogName, LogLevel.DEBUG);
                        } else {
                            loggingSystem.setLogLevel(sqlLogName, LogLevel.INFO);
                        }
                    });
                }
            });
        }
    }

    @EventListener
    public void handle(RefreshEvent event) {

        if (this.ready.get()) { // don't handle events before app is ready
            setLogLevel();
        }
    }

    @EventListener
    public void handle(ApplicationStartedEvent event) {
        //排除掉框架的日志
        loggingSystem.setLogLevel(LoggingSystem.ROOT_LOGGER_NAME, LogLevel.WARN);
    }

}